package me.fung.rem.component

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.*
import androidx.compose.ui.unit.Constraints

@Composable
fun CellLayout(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    Layout(
        modifier = modifier,
        content = content,
        measurePolicy = CellMeasurePolicy()
    )
}

@Composable
fun <T> CellLayout(
    data: Collection<T>,
    modifier: Modifier = Modifier,
    cellContent: @Composable (T) -> Unit,
) {
    CellLayout(modifier) {
        data.forEach {
            cellContent(it)
        }
    }
}

private class CellMeasurePolicy() : MeasurePolicy {
    override fun MeasureScope.measure(measurables: List<Measurable>, constraints: Constraints): MeasureResult {
        val placeableList = measurables.map { it.measure(constraints) }
        val cellWidth = placeableList.firstOrNull()?.width ?: 1
//        val cellHeight = placeableList.firstOrNull()?.height ?: 1
        val xSize: Int = countHorizontalSize(cellWidth, constraints.maxWidth)
        var ySize: Int = placeableList.size / xSize + (if (placeableList.size % xSize == 0) 0 else 1)
        if (ySize == 0) ySize = 1
        val xStartPosition: Int = (constraints.maxWidth - (cellWidth * xSize)) / 2
        val maxHeight = ySize * (+(placeableList.firstOrNull()?.height ?: 0))
        val c =
            constraints.copy(maxHeight = if (maxHeight < constraints.maxHeight) maxHeight else constraints.maxHeight)
        return layout(c.maxWidth, c.maxHeight) {
            var counter = 0
            var lineCounter = 0
            var xPosition: Int
            var yPosition = 0
            placeableList.forEach {
                counter++
                if (counter > xSize) {
                    counter = 1
                    lineCounter++
                    xPosition = xStartPosition
                    yPosition = it.height * lineCounter
                } else {
                    xPosition = xStartPosition + (cellWidth) * (counter - 1)
                }
                it.place(x = xPosition, y = yPosition)
            }
        }
    }

    private fun countHorizontalSize(placeableWidth: Int, maxWidth: Int): Int {
        if (placeableWidth < 1) return 1
        val count = maxWidth / placeableWidth
        if (count == 0) return 1
        return count
    }
}